'Copyright 2006 James Downey

Public Class Fetch

    '  <!--
    '  fetch element - root element for the query
    '-->
    '<ElementType name='fetch' content='eltOnly' model='closed'>
    '<AttributeType name='count' dt:type='int' required='no' />
    '<AttributeType name='page' dt:type='int' required='no' />
    '<AttributeType name='utc-offset' dt:type='int' required='no' />
    '<AttributeType name='aggregate' dt:type='boolean' required='no' />
    '<AttributeType name='mapping' dt:type='enumeration' 
    '               dt:values='logical' required='no' />
    '<AttributeType name='distinct' dt:type='enumeration' 
    '               dt:values='true false 1 0' required='no' default='false' />
    '<AttributeType name='paging-cookie' dt:type='string' required='no' />
    '  <!-- -->
    '<attribute type='count' />
    '<attribute type='page' />
    '<attribute type='utc-offset' />
    '<attribute type='aggregate' />
    '<attribute type='mapping' />
    '<attribute type='distinct' />
    '<attribute type='paging-cookie' />
    '<element type='entity' minOccurs='1' maxOccurs='1' />
    '</ElementType>

    'extra: version, output-format, distinct

    Public Count As Integer = -1 'value of -1 denotes user has not set value, do not include in query
    Public Page As Integer = -1
    Public UtcOffset As Integer = -1
    Public Aggregate As Boolean = False
    Public Mapping As Mapping = Mapping.logical
    Public Distinct As String = ""
    Public PagingCookie As String
    Private mEntity As Entity
    Public OutputFormat As String = ""
    Public Version As String = ""


    Public Sub New(ByVal EntityName As String)
        mEntity = New Entity(EntityName)
    End Sub

    Public Sub New()
    End Sub

    Public Sub New(ByVal FetchNode As Xml.XmlNode)
        If Not FetchNode.Attributes("version") Is Nothing Then
            Me.Version = FetchNode.Attributes("version").Value
        End If

        If Not FetchNode.Attributes("output-format") Is Nothing Then
            Me.OutputFormat = FetchNode.Attributes("output-format").Value
        End If
        If Not FetchNode.Attributes("count") Is Nothing Then
            Count = FetchNode.Attributes("count").Value
        End If
        If Not FetchNode.Attributes("page") Is Nothing Then
            Page = FetchNode.Attributes("page").Value
        End If
        If Not FetchNode.Attributes("utc-offset") Is Nothing Then
            UtcOffset = FetchNode.Attributes("utc-offset").Value
        End If
        If Not FetchNode.Attributes("aggregate") Is Nothing Then
            If FetchNode.Attributes("aggregate").Value = "true" Or FetchNode.Attributes("aggregate").Value = "1" Then
                Aggregate = True
            End If
        End If
        If Not FetchNode.Attributes("mapping").Value Is Nothing Then
            Select Case FetchNode.Attributes("mapping").Value
                Case "physical"
                    Me.Mapping = FetchXML.Mapping.physical
                Case "internal"
                    Me.Mapping = FetchXML.Mapping.internal
                Case Else
                    Me.Mapping = FetchXML.Mapping.logical
            End Select
        End If
        If Not FetchNode.Attributes("distinct") Is Nothing Then
            Distinct = FetchNode.Attributes("distinct").Value
        End If
        If Not FetchNode.Attributes("paging-cookie") Is Nothing Then
            PagingCookie = FetchNode.Attributes("paging-cookie").Value
        End If
        If Not FetchNode.Attributes("paging-cookie") Is Nothing Then
            PagingCookie = FetchNode.Attributes("paging-cookie").Value
        End If
        Dim entitynode As Xml.XmlNode
        entitynode = FetchNode.SelectSingleNode("./entity")
        mEntity = New Entity(entitynode)
    End Sub

    Public ReadOnly Property Entity() As Entity
        Get
            If mEntity Is Nothing Then
                Throw New ApplicationException("Entity property not yet set. Call SetEntity method.")
                Exit Property
            End If
            Return mEntity
        End Get
    End Property

    Public Sub SetEntity(ByVal EntityName As String)
        'calling this method will remove all of the 
        'data stored in the previous entity
        mEntity = New Entity(EntityName)
    End Sub

    Public Overrides Function ToString() As String
        Return ToXML()
    End Function

    Public Function ToXML() As String
        Dim strXML As String
        strXML = "<fetch "
        If Me.Version.Length > 0 Then
            strXML &= "version='" & Me.Version & "' "
        End If
        If Me.OutputFormat.Length > 0 Then
            strXML &= "output-format='" & Me.OutputFormat & "' "
        End If
        If Me.Count > 0 Then
            strXML &= "count='" & Me.Count & "' "
        End If
        Select Case Me.Mapping
            Case FetchXML.Mapping.logical
                strxml &= "mapping='logical' "
            Case FetchXML.Mapping.internal
                strxml &= "mapping='internal' "
            Case FetchXML.Mapping.physical
                strxml &= "mapping='physical' "
        End Select
        If Not Page = -1 Then
            strXML &= "page='" & Page.ToString & "' "
        End If
        If Not UtcOffset = -1 Then
            strXML &= "utc-offset='" & UtcOffset.ToString & "' "
        End If
        If Aggregate Then
            strXML &= "aggregate='true' "
        End If
        If Not Distinct.Length = 0 Then
            strXML &= "distinct='" & Distinct & "' "
        End If
        If Not PagingCookie Is Nothing AndAlso PagingCookie.Length > 0 Then
            strXML &= "paging-cookie='" & PagingCookie & "' "
        End If
        strXML &= ">"
        strXML &= Me.Entity.ToString
        strXML &= "</fetch>"
        Return strXML
    End Function

End Class

Public Enum Mapping
    logical
    internal
    physical
End Enum